#include <GL/glut.h>
#include <stdlib.h>
#include "simulate.h"


using namespace std;

Simulator* sim = new Simulator(.001);

void renderScene(void) {
     sim->updateStates();
        // notice that we're now clearing the depth buffer 
        // as well this is required, otherwise the depth buffer 
        // gets filled and nothing gets rendered. 
        // Try it out, remove the depth buffer part.
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
        // save the previous settings, in this case save 
        // we're refering to the camera settings.
        glPushMatrix();
        
        // Perform a rotation around the y axis (0,1,0) 
        // by the amount of degrees defined in the variable angle
    sim->renderShapes();        
        // discard the modelling transformations
        // after this the matrix will have only the camera settings.
        glPopMatrix();
        
        // swapping the buffers causes the rendering above to be 
        // shown
        glutSwapBuffers();
        
        // finally increase the angle for the next frame
}

void processKeys(unsigned char key, int x, int y) {

        if (key == 27) 
                exit(0);
}

void processFunctionKeys(int key, int x, int y){
    float mag=8;
        switch(key) {
        case GLUT_KEY_LEFT : 
        sim->applyUserForce(MyVec3(-mag,0,0));
        break;
        case GLUT_KEY_RIGHT : 
        sim->applyUserForce(MyVec3(mag,0,0));
        break;
    case GLUT_KEY_UP :
       sim->applyUserForce(MyVec3(0.0,0,-mag));
       break;
    case GLUT_KEY_DOWN :
      sim->applyUserForce(MyVec3(0.0,0,mag));
      break;
    
    }
}




void changeSize(int w, int h) {

        // Prevent a divide by zero, when window is too short
        // (you cant make a window of zero width).
        if(h == 0)
                h = 1;

        float ratio = 1.0* w / h;

        // Reset the coordinate system before modifying
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        
        // Set the viewport to be the entire window
        glViewport(0, 0, w, h);

        // Set the correct perspective.
        gluPerspective(45,ratio,1,1000);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(0.0,10.0,15.0, 
                      0.0,0.0,-1.0,
                          0.0f,1.0f,0.0f);

}

int main(int argc, char **argv) {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
        glutInitWindowPosition(100,100);
        glutInitWindowSize(500,500);
        glutCreateWindow("Rigid Body Simulation");
        glutDisplayFunc(renderScene);
        glutIdleFunc(renderScene);
        glutReshapeFunc(changeSize);
        glutKeyboardFunc(processKeys);
        glutSpecialFunc(processFunctionKeys);   
        sim->addShape(dynamic_cast<RigidBody*>(new CubeBody(1,1,1,1,1)));
        sim->addShape(dynamic_cast<RigidBody*>(new SphereBody(1,-1,1,1,1.5)));
        
        MyVec3 test1=MyVec3(1,1,1);
        MyVec3 test2=MyVec3(4,4,4);
        cout<<test1.getMagnitude()<<endl;
        
        cout<<distTwoPoints(test1,test2).n[0]<<","<<distTwoPoints(test1,test2).n[1]<<","<<distTwoPoints(test1,test2).n[2]<<endl;
        
        
        
    GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
    glShadeModel (GL_SMOOTH);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
        glutMainLoop();
        return 0;
}




